﻿; This file contains the code to add comments and modify details. 

; When an issue is double clicked, this will show the appriopriate details
view_issue(issueID)
{

; Load global vars
global language
global issues
global window_nums ; A special one just for this function (see AHK GUI 101 below)
global user_prefs
global comment_LV_var

; Load issue data (based on ID)
; We load a section and then break it apart with a nested parsing loop
; This is possible because the INI and section layout are consistent/predictable
section := ini_getsection(issues,"issue"issueID)

; Read one line at a time
Loop,parse,section, `n, `r
{
	line_name=
	line_contents=
	If A_Index > 1 ; Don't grab the section header ([issue##])
	{
		Loop,parse,A_loopfield,= ; Read chunks based on "="
		{
			If A_Index = 1 ; Grab the key
				line_name = %A_loopfield%
			If A_Index = 2 ; Grab/append the value (in case they used an "=" sign in their text
				line_contents := line_contents . A_loopfield
			If A_Index > 2  
				line_contents := line_contents . "=" . A_loopfield
		}
		; Put info in a dynamic (in this case, predictable) variable
		issue_%line_name% = %line_contents%
	}
}

; Format created time
If StrLen(issue_date) = "14"
	FormatTime,issue_date,%issue_date%,MM/dd/yyyy`, h:mm tt

; Load language strings
issue := get_language_string("issue",language)
createdon := get_language_string("createdon",language)
type := get_language_string("type",language)
priority := get_language_string("priority",language)
types := get_language_string("types",language)
priorities := get_language_string("priorities",language)
addcomment := get_language_string("addcomment",language)
updateissuedetails := get_language_string("updateissuedetails",language)
time := get_language_string("time",language)
comment := get_language_string("comment",language)
status := get_language_string("status",language)
exportHTML := get_language_string("exportHTML",language)

; Create window name
view_issue_win_name = %issue% %issueID% - %issue_subject%

; Is the issue already being viewed? If so, activate that window.
IfWinExist,%view_issue_win_name%
{
	WinActivate,%view_issue_win_name%
	Exit
}
	

; For these DDLs we need to make the current value in the issue the DDLs default value
; Build type list
; Typelist is a CSV, so we'll loop through values to build our list
typelist =
num_types = 1
Loop,parse, types,`,
{
	; If it's not a blank value
	If (A_Loopfield != "") 
	{	
		; Increment the counter that sets the dropdownlist height (number of options shown without scrolling)
		num_types += 1 
		
		If (A_Loopfield = issue_type) ; Make the appropriate item the selected one
			typelist=%typelist%%A_loopfield%||  ; Add it to our list (|| indicates it should be the default)
		Else
			typelist=%typelist%%A_loopfield%|  ; Add it to our list
	}
}

; Build priority list
prioritylist =
num_priorities = 1
Loop,parse, priorities,`,
{
	; If it's not a blank value
	If (A_Loopfield != "") 
	{
		num_priorities += 1 ; Increment the counter that sets the dropdownlist height (number of options shown without scrolling)
		
		If (A_loopfield = issue_priority) ; Make the appropriate item the selected one
			prioritylist=%prioritylist%%A_loopfield%||  ; Add it to our list
		Else
			prioritylist=%prioritylist%%A_loopfield%|
	}
}

; Build list of avilable statuses
statuses := get_language_string("initialstatus",language) .  "," . get_language_string("openstatuses",language) . "," . get_language_string("closedstatuses",language)
statuslist=
num_statuses = 1
Loop,parse, statuses,`,
{
	; If it's not a blank value
	If (A_Loopfield != "") 
	{
		num_statuses += 1 ; Increment the counter that sets the dropdownlist height (number of options shown without scrolling)
		
		If (A_loopfield = issue_status) ; Make the appropriate item the selected one
			statuslist=%statuslist%%A_loopfield%||  ; Add it to our list 
		Else
			statuslist=%statuslist%%A_loopfield%|
	}
}
; Listview Color
comment_LVcolor := ini_getvalue(user_prefs,"listviewcolors","comments")


; Short story about GUIs in AHK
; There can be 100 GUIs, and each has to have a unique number for us to work with it
; Otherwise, each newly viewed issue would overwrite the old window's data

; To work with that, we start with a CSV list of avialable number
; We take the first number when we open a GUI, and put it back at the end when we're done
; This way, we can have as many issue GUIs open as possible

; If I need an extra GUI number for something like an option dialog...
; ...I can just remove it from the CSV list and never have to worry about a conflict
; It has it similarities to a mixed Static/Dynamic IP addressing system

; Go through the window #s
Loop,Parse,window_nums,`,
{
	If A_Loopfield is number ; to avoid double commas
	{
		StringReplace,window_nums,window_nums,%A_Loopfield%`,,,
		gui_num = %A_Loopfield%
		
		break ; Leave loop after grabbing our value
		
	}
}

; Gui commands assume the current GUI #
Gui,%gui_num%:Default

; Text values
Gui, Add, Text, x12 y10 w360 h20 , %view_issue_win_name%
Gui, Add, Text, x12 y43 w70 h20 , %createdon%:
Gui, Add, Text, x82 y43 w110 h20 , %issue_date%
Gui, Add, Text, x12 y83 w60 h20 , %type%:
Gui, Add, Text, x202 y83 w70 h20 , %priority%:
Gui, Add, Text, x12 y113 w60 h20 , %status%:

; Dropdownlists
Gui, Add, DropDownList, x272 y80 w100 h20 r%num_priorities%, %prioritylist%
Gui, Add, DropDownList, x82 y80 w100 h20 r%num_types%, %typelist%
Gui, Add, DropDownList, x82 y110 w100 h20 r%num_statuses%, %statuslist%

; Buttons
Gui, Add, Button, x12 y140 w120 h40 gaddcommentbutton, %addcomment%
Gui, Add, button, x142 y140 w120 h40 gupdateissuedetails, %updateissuedetails%
Gui, Add, Button, x272 y140 w100 h40 , %exportHTML%

; Listview
Gui, Add, ListView, x20 y220 w354 h204 vcomment_LV_var, %time%|%comment%
; LVA_ListViewAdd(comment_LV_var,"AR RB0x"comment_LVcolor)

; Store/Hide Issue ID within GUI (easier than using RegEx on a window title)
Gui,Add,text,x10 y10,%issueID%
GuiControl,hide,static7 

Gui,+Resize ; Allow the GUI to be resized
Gui,+Labelviewedissue ; Set one label to be used for all issue resize/closing operations
GuiControl,disable,button3 ; Grey out HTML button until feature is implemented



; Generated using SmartGUI Creator 4.0
Gui, Show, h425 w380, %view_issue_win_name%

; Change it's size to the same it is now, resolves issue where the LV would be in a random other spot
;WinGetPos,,,win_width,win_height,%view_issue_win_name%
;ControlMove,syslistview321,20,220, A_GuiWidth - 22, A_GuiHeight - 202,%view_issue_win_name%

;Msgbox, %win_width% x %win_height%
list_comments(gui_num)
Return

; Add comment button
addcommentbutton:
	; Load language strings
	global language

	; Get issueID
	WinGetActiveTitle,issueviewertitle 
	ControlGetText,issueID,static7,%issueviewertitle% ; Grab from active window

	; Get language strings for input box
	comment := get_language_string("comment",language)
	addcomment := get_language_string("addcomment",language)

	; Prompt user for comment
	InputBox,user_comment,%addcomment%,%comment%:,,385,130
	If Errorlevel ; If they close it without entering anything...
		Return ; Act like this never happened

	; Add the comment/refresh the list
	new_comment(user_comment,IssueID)
	list_comments(A_Gui)
	WinActivate,%issueviewertitle%
Return

; Detail updating
updateissuedetails:

; Access global vars
global issues
global language
global data_dir

; Load language strings
willbechangedto := get_language_string("willbechangedto",language)
status := get_language_string("status",language)
priority := get_language_string("priority",language)
type := get_language_string("type",language)
confirmchanges := get_language_string("confirmchanges",language)

; Get issueID
WinGetActiveTitle,issueviewertitle ; Grab from active window
ControlGetText,issueID,static7,%issueviewertitle% 

; Detail grabbing loop
details=%priority%,%type%,%status%
updatemsg=
Loop,parse,details,`,
{

	; Look up old option
	If (A_Index = "1")
		old_%A_loopfield% := ini_getvalue(issues,"issue"issueID,"priority")
	Else If (A_Index = "2")
		old_%A_loopfield% := ini_getvalue(issues,"issue"issueID,"type")
	Else If (A_Index = "3")
	{
		old_%A_loopfield% := ini_getvalue(issues,"issue"issueID,"status")
		oldstatus := old_%A_loopfield%
		; Msgbox, Old: %oldstatus%
	}
	
	; Grab new one
	ControlGet,new_%A_Loopfield%,Choice,,Combobox%A_Index%,%issueviewertitle%
	

	; Compare/build update list
	If (old_%A_loopfield% != new_%A_loopfield%)
		updatemsg := updatemsg . A_loopfield . " " . willbechangedto . " " . new_%A_loopfield% . ".`n"
}


; Is the issue open or closed now?
open_statuses := get_language_string("initialstatus",language) . "," . get_language_string("openstatuses",language) . ","
block1=%oldstatus%,
block2=,%oldstatus%,

; Check if the status is in front or otherwise in the open list
If (InStr(open_statuses,block1) = 1) || If (InStr(open_statuses,block2,"2") > 2)
	old_issue_type = open
Else
	old_issue_type=closed

; Loop,parse,open_statuses,`,
; {
	; If (A_Loopfield != "")
	; {
		; If (oldstatus = A_loopfield)
		; {
			; old_issue_type = open
			; Break
		; }
	
	; }
; }
; If !(old_issue_type)
	; old_issue_type=closed

;Msgbox, %open_statuses%
;Msgbox, %old_issue_type%
	
; Remove commas (sometimes they get grabbed)
StringReplace,updatemsg,updatemsg,`,,,ReplaceAll

; If there were changes
If updatemsg
{
	Msgbox,8196,%confirmchanges%,%updatemsg%
	IfMsgbox Yes
	{
		; Grab language string
		waschangedto := get_language_string("waschangedto",language)
		
		; Set file path
		; temp=%data_dir%\Issues\issue%IssueID%.ini
		; If FileExist(temp) ; If the issue is a temp file
			; issues_ini=%data_dir%\Issues\issue%IssueID%.ini ; Write the data there instead
		; Else
			; issues_ini=%data_dir%\Issues\issues.ini
		
		; oldsection := ini_getsection(issues,"issue"issueID)
		
		
		; Loop to add comments/write changes
		details=%priority%,%type%,%status%
		;item=0
		Loop,parse,details,`,
		{
			
			
			; Look up old option
;			old_%A_loopfield% := ini_getvalue(issues,"issue"issueID,A_loopfield)
			; Look up old option
			If (A_Index = "1")
				old_%A_loopfield% := ini_getvalue(issues,"issue"issueID,"priority")
			Else If (A_Index = "2")
				old_%A_loopfield% := ini_getvalue(issues,"issue"issueID,"type")
			Else If (A_Index = "3")
				old_%A_loopfield% := ini_getvalue(issues,"issue"issueID,"status")
			
			; Grab new one
			ControlGet,new_%A_Loopfield%,Choice,,Combobox%A_Index%,%issueviewertitle%
			
			; Add comment
			If (old_%A_loopfield% != new_%A_loopfield%)
			{
				; Build comment
				comment := A_loopfield . " " . waschangedto . " " . new_%A_loopfield% . ".`n"
				
				; Remove commas (sometimes they get grabbed)
				StringReplace,comment,comment,`,,,ReplaceAll
				
				; Add comment
				new_comment(comment,issueID)
				;Msgbox, %A_Index%
				
				;new_value := new_%A_loopfield%
				;Msgbox, %new_value%
				
				; Write issue changes to memory
				If (A_Index = "1") ; Priority
					ini_replaceValue(issues,"issue"issueID,"priority",new_%A_loopfield%)

				Else If (A_Index = "2") ; Type
					ini_replaceValue(issues,"issue"issueID,"type",new_%A_loopfield%)

				Else If (A_Index = "3") ; Status
				{
					ini_replaceValue(issues,"issue"issueID,"status",new_%A_loopfield%)
					newstatus := new_%A_loopfield%
					;Msgbox, New: %newstatus%
				}
			}
			; Special counter
			;item+=1
		}

		;newsection := ini_getsection(issues,"issue"issueID)
		
		;Msgbox,Old:%oldsection%`n`nNew:%newsection%
		; Status changing code
		;ListVars
		;Pause
		
		;Msgbox, %oldstatus% -- %newstatus%
		; old_%status%
		If (newstatus) ; Only run if the status has been changed (there's a new status)
		If (oldstatus != newstatus)
		{
			;Msgbox, I'm in!
			; Is the issue open or closed now?
			open_statuses := get_language_string("initialstatus",language) . "," . get_language_string("openstatuses",language) . ","
			block1=%newstatus%,
			block2=,%newstatus%,

			; Check if the status is in front or otherwise in the open list
			If (InStr(open_statuses,block1) = 1) || If (InStr(open_statuses,block2) > 2)
				new_issue_type = open
			Else
				new_issue_type = closed
			
			;result1 := InStr(open_statuses,block1)
			;result2 := InStr(open_statuses,block2)
			
			;Msgbox,%open_statuses%`n%result1% : %block1%`n%result2% : %block2%
			; Old checking method
			; Loop,parse,open_statuses,`,
			; {
				; If (A_Loopfield != "")
				; {
					; If (newstatus = A_loopfield) ; If it's on the open list...
					; {
						; new_issue_type = open
						; Msgbox, %open_statuses%
						; Break
					; }
				
				; }
			; }
			; If !(new_issue_type) ; If it isn't...
				; new_issue_type = closed
			
			;Msgbox, Types: %old_issue_type% -- %new_issue_type%
			
			; Compare statuses
			; If they're the same as before, no changes need to be made
			; Otherwise, remove the issueID from it's list, add it to the other, and save the changes
			open_issues := ini_getvalue(issues,"issues","open")
			closed_issues := ini_getvalue(issues,"issues","closed")
			If (new_issue_type != old_issue_type) ; Not the same as before?
			{
				If (new_issue_type = "closed") ; Now closed
				{
					;before = %closed_issues%
					Loop, parse,open_issues,`,
					{
						If (A_loopfield = issueID) ; Make sure we grab the right number (i.e. don't mix up 1 with 11 with 111 by doing a blind replacement
						{
							If (A_Index = "1") ; If it's in front of the list it won't have a preceding comma
								StringReplace,open_issues,open_issues,%issueID%`,,,
							Else ; Otherwise, it will
							{
								StringReplace,open_issues,open_issues,`,%issueID%`,,`,,
								StringReplace,open_issues,open_issues,`,%issueID%,`,,
							}
							closed_issues = %closed_issues%%issueID%, ; Add it to the closed list
							Break
						}
					}
					;after = %closed_issues%
					;Msgbox, %before%`n%after%
					
				}
				Else If (new_issue_type = "open") ; Now open
				{
					;before = %open_issues%
					Loop,parse,closed_issues,`,
					{
					
						If (A_Loopfield = issueID)
						{
							If (A_Index = "1")
								StringReplace,closed_issues,closed_issues,%issueID%`,,,
							Else
							{
								StringReplace,closed_issues,closed_issues,`,%issueID%`,,`,,
								StringReplace,closed_issues,closed_issues,`,%issueID%,`,,
								;Msgbox, %closed_issues%
							}
												
						open_issues = %open_issues%%issueID%,
						Break					
						}
					}
					
					
					;after = %open_issues%
					;Msgbox, %before%`n%after%
					
				}
			
			; Sort items for readability when listing
			;Sort,open_issues,D,
			;Sort,closed_issues,D,
			
			Sort,open_issues, F IntegerSort D,
			Sort,closed_issues, F IntegerSort D,
			
			; Update lists in memory
			ini_replaceValue(issues,"issues","closed",closed_issues)
			ini_replaceValue(issues,"issues","open",open_issues)
			
				
			; Write changes to HD
			; Temp update
			issues_ini=%data_dir%\Issues\issues.ini
			IniRead,temp_list,%issues_ini%,issues,temp
			temp_id1=,%issueID%,
			temp_id2:= "=" . issueID . ","
			;Msgbox, %temp_id1%`n%temp_id2%
			If (InStr(temp_list,temp_id1)) || If (InStr(temp_list,temp_id2))
				in_list=1 ; If it's in the temp list already, don't add it in again
			Else
				IniWrite,%temp_list%%issueID%`,,%issues_ini%,issues,temp
			
			; Open/Closed Update
			IniWrite,%open_issues%,%issues_ini%,issues,open
			IniWrite,%closed_issues%,%issues_ini%,issues,closed
			
			; Write issue section to temp file
			temp_path=%data_dir%\Issues\issue%issueID%.ini
			issue_data := ini_getsection(issues,"issue"issueID)
			ini_save(issue_data,temp_path)
		}
		}
		Else ; If the status didn't change, write the other changes
		{
			; Write changes to HD
			; Temp update
			issues_ini=%data_dir%\Issues\issues.ini
			IniRead,temp_list,%issues_ini%,issues,temp
			temp_id1=,%issueID%,
			temp_id2:= "=" . issueID . ","
			;Msgbox, %temp_id1%`n%temp_id2%
			If (InStr(temp_list,temp_id1)) || If (InStr(temp_list,temp_id2))
				in_list=1 ; If it's in the temp list already, don't add it in again
			Else
				IniWrite,%temp_list%%issueID%`,,%issues_ini%,issues,temp
			
			
			
			
			;			IniRead,temp_list,%issues_ini%,issues,temp
;			IniWrite,%temp_list%%issueID%`,,%issues_ini%,issues,temp

			; Write issue section to temp file
			temp_path=%data_dir%\Issues\issue%issueID%.ini
			issue_data := ini_getsection(issues,"issue"issueID)
			ini_save(issue_data,temp_path)
		}
	}
}

list_comments(A_Gui)
list_issues()
Return




; Resize listview based on window size
viewedissuesize:
	WinGetActiveTitle,issueviewertitle
	ControlMove,syslistview321,20,220, A_GuiWidth - 22, A_GuiHeight - 202,%issueviewertitle%
	LV_ModifyCol(2,"AutoHDR") ; Resize 2nd column
Return

; On close, return the GUI # to the "pool" and free the memory
viewedissueclose:
	window_nums=%window_nums%,%A_Gui%
	Gui,%A_Gui%:Destroy
Return
}



; This function reads the commentIDs from an issue and lists them in the respective GUI
list_comments(gui_num)
{
; Access global data
global issues
global comments

; Get issueID
WinGetActiveTitle,issueviewertitle 
ControlGetText,issueID,static7,%issueviewertitle% ; Grab from active window

; Get commentIDs
commentIDs := ini_getvalue(issues,"issue"issueID,"commentIDs")

; Set default GUI (for LV updates)
Gui,%gui_num%:Default

; Hide the listview
Control,Hide,,Syslistview321,%issueviewertitle%

; Clear it 
LV_Delete()  ; Clear all rows from the ListView.


; Go through comment IDs
Loop,Parse,commentIDs,`,
{
	If (A_loopfield != "") ; Avoid blank IDs
	{
		comment_section := ini_getsection(comments,"comment"A_loopfield)

		; Read one line at a time
		Loop,parse,comment_section, `n, `r
		{
			line_name=
			line_contents=
			If A_Index > 1 ; Don't grab the section header ([issue or comment##])
			{
				Loop,parse,A_loopfield,= ; Read chunks based on "="
				{
					If A_Index = 1 ; Grab the key
						line_name = %A_loopfield%
					If A_Index = 2 ; Grab/append the value (in case they used an "=" sign in their text
						line_contents := line_contents . A_loopfield
					If A_Index > 2  
						line_contents := line_contents . "=" . A_loopfield
				}
				; Put info in a dynamic (in this case, predictable) variable
				comment_%line_name% = %line_contents%
			}
		}
		FormatTime,comment_date,%comment_date%,M/d @ h:mmtt
		LV_Add("",comment_date,comment_comment)
	}
}

; Resize col headers
Loop,2
	LV_ModifyCol(A_Index,"AutoHDR")



; Show the listview
Control,Show,,Syslistview321,%issueviewertitle%

Return
}

; Used for sorting issue #s
IntegerSort(a1, a2)
{
	return a1 - a2  ; Sorts in ascending numeric order.  This method works only if the difference is never so large as to overflow a signed 64-bit integer.
}